package com.biz.primus.management.order.controller;

import com.biz.primus.account.utils.SSOUtils;
import com.biz.primus.base.vo.PageResult;
import com.biz.primus.common.utils.JsonUtils;
import com.biz.primus.common.vo.SpringPageVO;
import com.biz.primus.management.order.feign.GeoFeignClient;
import com.biz.primus.management.order.feign.OmsFeignClient;
import com.biz.primus.management.order.feign.StockFeignClient;
import com.biz.primus.model.geo.vo.AreaResponseVo;
import com.biz.primus.model.oms.enums.OrderDeliveryType;
import com.biz.primus.model.oms.enums.OrderOperatorSource;
import com.biz.primus.model.oms.enums.OrderPaymentState;
import com.biz.primus.model.oms.enums.OrderState;
import com.biz.primus.model.oms.vo.*;
import com.biz.primus.model.stock.vo.DepotMeetStockRespVo;
import com.biz.primus.model.stock.vo.NearMeetStockDepotReqVo;
import com.fasterxml.jackson.databind.util.JSONPObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author zzy
 * @rema 派单控制器
 * @date 2017/11/14/008
 */
@Controller
@RequestMapping("dispatch")
public class DispatchController {

    @Autowired
    private OmsFeignClient omsFeignClient;

    @Autowired
    private GeoFeignClient geoFeignClient;

    @Autowired
    private StockFeignClient stockFeignClient;

    /**
     * 已派单列表(首页,跳转)
     * @return
     */
    @GetMapping
    public ModelAndView index () {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("dispatch/list");
        return modelAndView;
    }

    /**
     * 订单跳转详情
     * @return
     */
    @GetMapping("details")
    public ModelAndView details () {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("dispatch/details");
        return modelAndView;
    }

    /**
     * 详情跳转取消订单
     * @return
     */
    @GetMapping("cancelOrder")
    public ModelAndView cancelOrder () {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("dispatch/cancelOrder");
        return modelAndView;
    }

    /**
     * 详情跳转改派
     * @return
     */
    @GetMapping("reassignment")
    public ModelAndView reassignment () {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("dispatch/reassignment");
        return modelAndView;
    }

    /**
     * 详情跳转改派
     * @return
     */
    @GetMapping("modifyTheReceiving")
    public ModelAndView modifyTheReceiving () {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("dispatch/modifyTheReceiving");
        return modelAndView;
    }

    /**
     * 订单管理(处理页面获取数据,查询,刷新)
     * @return 前端使用datatable 必须使用aadata为key返回
     * @Exc     分页参数错误
     */
    @GetMapping("list")
    @ResponseBody
    public Map<String, Object> list (OrderDeliveryType state, String orderCode, int start, int length) {
        // 分页数据判断(datatable 分页数是0开始的)
        if (start < 0 && length < 1) {
            try {
                throw new Exception("分页参数错误");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        OrderQueryVo orderQueryVo = new OrderQueryVo();

        List<OrderState> orderQueryVos = new LinkedList<>();

        // 查询=>已分单
        orderQueryVos.add(OrderState.allocated);
        // 设置订单状态
        orderQueryVo.setOrderState(orderQueryVos);
        // 设置配送方式
        if (state != null) {orderQueryVo.setOrderDeliveryTypes(state);}
        // 设置订单编码
        if (StringUtils.isBlank(orderCode)) {orderQueryVo.setOrderCode(orderCode);}

        // 添加分页数据
        orderQueryVo.setPage(start+1);
        orderQueryVo.setSize(length);

//        PageResult<OmsOrderVo> omsOrderVoSpringPageVO = omsFeignClient.managementOrderQuery(orderQueryVo);
        List<OmsOrderVo> omsOrderVoSpringPageVO  = getAll();
        // 返回值
        Map<String, Object> result = new HashMap<>();
        //数据总条数
//        result.put("iTotalRecords", omsOrderVoSpringPageVO.getTotalPage());
//        //显示的条数
//        result.put("iTotalDisplayRecords", omsOrderVoSpringPageVO.getCurrentPage());
//        result.put("aaData", omsOrderVoSpringPageVO.getContent());

        result.put("iTotalRecords", omsOrderVoSpringPageVO.size());
        //显示的条数
        result.put("iTotalDisplayRecords", omsOrderVoSpringPageVO.size());
        result.put("aaData", omsOrderVoSpringPageVO);
        return result;
    }

    /**
     * 订单详情
     * @return 前端使用datatable 必须使用aadata为key返回
     * @Exc     订单编码缺失
     */
    @GetMapping("detailsData")
    @ResponseBody
    public OmsOrderRespVo detailsData (String orderCode) {
        if (StringUtils.isBlank(orderCode)) {
            try {
                throw new Exception("订单编码缺失");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return omsFeignClient.getOrderDetail(orderCode);
    }
    /**
     * 省市区联动查询
     * @param level     查询维度(0 省,1 市, 2 区)
     * @param code      查询id(省份查询不传递)
     * @return          省市区,单层级集合
     * @exc             查询维度错误
     *                  缺少id
     */
    @GetMapping("level2")
    @ResponseBody
    public List<AreaResponseVo> level2 (int level, Long code) throws Exception {
        if (level < 0 || level > 2) {
            throw new Exception("省市区联动查询,查询维度错误");
        }
        // 查询'省'层级
        if (level == 0) {
            return geoFeignClient.findAllProvince();
        }
        if (code == null) {
            throw new Exception("省市区联动查询,缺少id");
        }
        // 查询'市'层级
        if (level == 1) {
            return geoFeignClient.findCitiesByProvinceId(code);
        }
        // 查询'区/县'层级
        return geoFeignClient.findDistrictsByCityId(code);
    }

    /**
     * 获取指定门店附近满足库存的门店
     * @param lat               维度
     * @param lon               经度
     * @param productCode       产品编码
     * @param quantity          数量
     * @return                  附近满足库存的门店集合
     * @Exc                     缺少参数
     */
    @PostMapping("getNearMeetStockDepots")
    @ResponseBody
    public List<DepotMeetStockRespVo> getNearMeetStockDepots(String lat, String lon, String productCode, Integer quantity) throws Exception {
        if (StringUtils.isBlank(lat) || StringUtils.isBlank(lon) || StringUtils.isBlank(productCode) || quantity == null) {
            throw new Exception("获取指定门店附近满足库存的门店,缺少参数");
        }

        BigDecimal latB = new BigDecimal(lat);
        BigDecimal lonB = new BigDecimal(lon);

        // 设置查询条件
        NearMeetStockDepotReqVo reqVo = new NearMeetStockDepotReqVo();
        reqVo.setLat(latB);
        reqVo.setLon(lonB);
        reqVo.setProductCode(productCode);
        reqVo.setQuantity(quantity);

        return stockFeignClient.getNearMeetStockDepots(reqVo);
    }

    /**
     * 收货信息变更保存
     * @param code                  订单编码
     * @param consigneeName         收货人姓名
     * @param consigneeMobile       收货人联系手机
     * @param address               详细地址
     * @param lat                   纬度,6位小数
     * @param lon                   经度,6位小数
     * @param provinceId            geo 省id
     * @param cityId                geo 市id
     * @param districtId            geo 区县id
     * @param provinceText
     * @param cityText
     * @param districtText
     * @param modifyRemark          后台修改收货人时的备注信息
     * @param email                 邮箱
     * @param postcode              邮编
     */
    @PostMapping("changeConsigneeInfo")
    public void changeConsigneeInfo(String code,
                                    String consigneeName,
                                    String consigneeMobile,
                                    String address,
                                    String lat,
                                    String lon,
                                    Long provinceId,
                                    Long cityId,
                                    Long districtId,
                                    String provinceText,
                                    String cityText,
                                    String districtText,
                                    String modifyRemark,
                                    String email,
                                    String postcode) throws Exception {
        if (StringUtils.isBlank(code)) {
            throw new Exception("收货信息变更保存,订单编码不可或缺");
        }
        ChangeShippingInfoRequest changeShippingInfoRequest = new ChangeShippingInfoRequest();
        //中台默认客服操作
        changeShippingInfoRequest.setSource(OrderOperatorSource.cs);
        changeShippingInfoRequest.setCode(code);
        //收货信息请求对象
        OmsConsigneeVo omsConsigneeVo = new OmsConsigneeVo();
        if (StringUtils.isNotBlank(consigneeName)) {
            if (consigneeName.getBytes().length > 20) {
                throw new Exception("收货信息变更保存,收货人姓名,字节大于20");
            }
            omsConsigneeVo.setConsigneeName(consigneeName);
        }
        if (StringUtils.isNotBlank(consigneeMobile)) {
            if (consigneeMobile.getBytes().length > 20) {
                throw new Exception("收货信息变更保存,收货人电话,字节大于20");
            }
            omsConsigneeVo.setConsigneeMobile(consigneeMobile);
        }
        if (StringUtils.isNotBlank(address)) {
            if (consigneeMobile.getBytes().length > 100) {
                throw new Exception("收货信息变更保存,地址详情,字节大于100");
            }
            omsConsigneeVo.setAddress(address);
        }
        if (StringUtils.isNotBlank(lat)) {
            omsConsigneeVo.setLat(new BigDecimal(lat));
        }
        if (StringUtils.isNotBlank(lon)) {
            omsConsigneeVo.setLon(new BigDecimal(lon));
        }
        if (provinceId != null) {
            omsConsigneeVo.setProvinceId(provinceId);
        }
        if (cityId != null) {
            omsConsigneeVo.setCityId(cityId);
        }
        if (districtId != null) {
            omsConsigneeVo.setDistrictId(districtId);
        }
        if (StringUtils.isNotBlank(provinceText)) {
            omsConsigneeVo.setProvinceText(provinceText);
        }
        if (StringUtils.isNotBlank(cityText)) {
            omsConsigneeVo.setCityText(cityText);
        }
        if (StringUtils.isNotBlank(districtText)) {
            omsConsigneeVo.setDistrictText(districtText);
        }
        if (StringUtils.isNotBlank(modifyRemark)) {
            omsConsigneeVo.setModifyRemark(modifyRemark);
        }
        if (StringUtils.isNotBlank(email)) {
            omsConsigneeVo.setEmail(email);
        }
        if (StringUtils.isNotBlank(postcode)) {
            omsConsigneeVo.setPostcode(postcode);
        }
        changeShippingInfoRequest.setConsignee(omsConsigneeVo);
        //修改收货信息
        omsFeignClient.changeConsigneeInfo(changeShippingInfoRequest);
    }

    /**
     *  改派(改派订单提交没有拆单)
     * @param code              订单编码
     * @param targetDepotCode   改派的目标门店
     * @throws Exception
     */
    @PostMapping("/dispatching")
    public void  dispatching(String code,
                             String targetDepotCode) throws Exception {
        if (StringUtils.isBlank(code)) {
            throw new Exception("改派(改派订单提交没有拆单),订单编码不可或缺");
        }
        if (StringUtils.isBlank(targetDepotCode)) {
            throw new Exception("改派(改派订单提交没有拆单),改派的目标门店不可或缺");
        }
        OrderPostRequest req = new OrderPostRequest();
        req.setCode(code);
        //中台默认客服操作
        req.setSource(OrderOperatorSource.cs);
        OrderDispatchingRequest orderDispatchingRequest = new OrderDispatchingRequest(req, targetDepotCode, "客服后台申请改派");
        // 改派
        omsFeignClient.dispatching(orderDispatchingRequest);
    }

    /**
     * 拆单(改派订单提交拆单)
     * @param orderCode     订单编码
     * @param splitItems    拆分商品及数量
     * @param splitRemark   拆单备注
     */
    @PostMapping("orderSplit")
    public void orderSplit(String orderCode,
                           String splitItems,
                           String splitRemark) throws Exception {
        if (StringUtils.isBlank(orderCode)) {
            throw new Exception("拆单(改派订单提交拆单),订单编码不可或缺");
        }

        if (splitItems == null || splitItems.length() == 0) {
            throw new Exception("拆单(改派订单提交拆单),拆分商品及数量不可或缺");
        }

        List<SplitItemVo> splitItemVos = JsonUtils.json2Obj(splitItems, List.class, SplitItemVo.class);

        SplitRequestVo splitRequestVo = new SplitRequestVo();
        splitRequestVo.setOrderCode(orderCode);
        splitRequestVo.setSplitItems(splitItemVos);
        splitRequestVo.setSplitRemark(splitRemark.length() == 0 ? null : splitRemark);

        splitRequestVo.setOperator(SSOUtils.getUserOfLogin().getId());
        // 拆单
        omsFeignClient.orderSplit(splitRequestVo);
    }


    private List<OmsOrderVo> getAll() {
        List<OmsOrderVo>  result = new LinkedList<>();
        for (int j = 0; j < 6; j++) {
            OmsOrderVo orderItemVO = new OmsOrderVo();
            orderItemVO.setCode("订单编码" + j);
            orderItemVO.setOrderSource("订单来源" + j);
            orderItemVO.setSelfRemark("商家备注" + j);
            orderItemVO.setDeliveryType(OrderDeliveryType.self_now);
            orderItemVO.setPaymentState(OrderPaymentState.cod);
            orderItemVO.setAmount(j);
            orderItemVO.setDeliveryType(OrderDeliveryType.self_now);
            result.add(orderItemVO);
        }
        return result;
    }
}
